package cn.hxth.dubbo.customer.controller;

import cn.hxth.api.model.Product;
import cn.hxth.api.model.ProductBaseInfo;
import cn.hxth.api.model.ProductSpec;
import cn.hxth.api.query.PageResult;
import cn.hxth.api.query.ProductQueryObject;
import cn.hxth.api.request.Request;
import cn.hxth.api.service.IProductBaseInfoService;
import cn.hxth.api.service.IProductNameService;
import cn.hxth.api.service.IProductService;
import cn.hxth.api.service.IProductSpecService;
import cn.hxth.api.util.RequestAsyncProcess;
import cn.hxth.dubbo.customer.request.ProductBaseInfoCacheRefreshRequest;
import cn.hxth.dubbo.customer.request.ProductBaseInfoDBUpdateRequest;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/pages/product/")
public class ProductController {
    @Resource
    private IProductBaseInfoService productBaseInfoService;
    @Resource
    private IProductService productService;
    @Resource
    private IProductNameService productNameService ;
    @Resource
    private IProductSpecService productSpecService ;
    @Resource(name = "myRedisTemplate")
    private RedisTemplate<String,Object> redisTemplate ;
@RequestMapping("insertProduct")
    public boolean insertProduct(Product product, ProductBaseInfo productBaseInfo) {
    // 判断该新增的商品的规格是不是已存在相关的商品(我的表关系设计有问题，所以多了这一步判断)
    Long pid = this.productService.getPidBySid(product.getSpec().getSid()) ;
    if(pid!=null){
       // System.out.println(pid);
        try {
            throw  new RuntimeException("此商品或规格已存在（商品规格和商品是一对一关系）") ;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  false ;
    }

    boolean flag = productService.insertProduct(product,productBaseInfo) ;

       return  flag ;

    }
@RequestMapping("updateProduct")
    public boolean updateProduct(Product product, ProductBaseInfo productBaseInfo) {
        productBaseInfo.setPid(product.getPid());
        // 如果此次商品修改修改了商品核心信息
        if (productBaseInfo.getInventory() != null || productBaseInfo.getPrice() != null || (productBaseInfo.getLin() != null && !productBaseInfo.getLin().equals(""))) {

            System.out.println("===========日志===========: 接收到更新商品库存的请求，商品id=" + productBaseInfo.getPid() + ", 商品库存数量=" + productBaseInfo.getInventory());


            Request request = new ProductBaseInfoDBUpdateRequest(productBaseInfo, productBaseInfoService);
            RequestAsyncProcess.process(request);


        }
        return this.productService.updateProduct(product);
    }
    @RequestMapping("getProduct")
    public  String getProduct(long pid){

           // 从缓存中取得该商品的完整信息
           String dimInfo = (String) this.redisTemplate.opsForValue().get("dim_product_"+pid);
           if(dimInfo!=null){
               return  dimInfo ;
           }
           // 取得商品部分信息
        JSONObject jsonObject = JSONObject.parseObject(this.productService.getProduct(pid)) ;
        // 取得商品的规格编号
        Integer sid = jsonObject.getJSONObject("spec").getInteger("sid");
        // 取得该商品规格的完整信息
        ProductSpec spec = this.productSpecService.getProductSpec(sid) ;
        //System.out.println(JSONObject.toJSONString(spec));
        //取得该商品规格对应的商品名称
        spec.setProductName(this.productNameService.getProductName(spec.getProductName().getNid()));
       // JSONObject specJson = JSONObject.parseObject(JSONObject.toJSONString(spec)) ;
        // 完善商品信息json串内容
        jsonObject.put("spec",spec) ;
        // 将此商品信息放入redis
      this.redisTemplate.opsForValue().set("dim_product_"+pid,jsonObject.toJSONString());
     // System.out.println(this.redisTemplate.opsForValue().get("dim_product_"+pid));
      return   jsonObject.toJSONString() ;

    }
    @RequestMapping("listProducts")
    public PageResult listProducts(ProductQueryObject productQueryObject){
       PageResult pageResult = productService.getProductList(productQueryObject) ;
        List listData = pageResult.getListData();
        for(Object object:listData){
            Map<String,Object> map = (Map<String, Object>) object;
            Product product = (Product) map.get("product");
            ProductSpec spec = this.productSpecService.getProductSpec(product.getSpec().getSid()) ;
           spec.setProductName( this.productNameService.getProductName(spec.getProductName().getNid())) ;
            product.setSpec(spec);

        }
        return  pageResult ;
    }
    @RequestMapping("deleteProduct")
    public  boolean deleteProduct(long pid){
        return  this.productService.deleteProduct(pid) ;
    }
    @RequestMapping("getProductBaseInfo")
    public ProductBaseInfo getProductBaseInfo(Long pid) throws InterruptedException {


        System.out.println("===========日志===========: 接收到一个商品库存的读请求，商品id=" + pid);

        ProductBaseInfo productBaseInfo = null;


            Request request = new ProductBaseInfoCacheRefreshRequest(pid,productBaseInfoService,false);
            RequestAsyncProcess.process(request);


            long startTime = System.currentTimeMillis();
            long endTime = 0L;
            long waitTime = 0L;


            while(true) {

                if(waitTime > 200) {
                    break;
                }


                productBaseInfo = productBaseInfoService.getProductBaseInfoCache(pid);


                if(productBaseInfo != null) {
                    System.out.println("===========日志===========: 在200ms内读取到了redis中的库存缓存，商品id=" + productBaseInfo.getPid() + ", 商品库存数量=" + productBaseInfo.getInventory());
                    return productBaseInfo;
                }


                else {
                    Thread.sleep(20);
                    endTime = System.currentTimeMillis();
                    waitTime = endTime - startTime;
                }
            }


            productBaseInfo = productBaseInfoService.getProductBaseInfo(pid);
            if(productBaseInfo != null) {
                request = new ProductBaseInfoCacheRefreshRequest(
                        pid, productBaseInfoService, true);
                RequestAsyncProcess.process(request);

                return productBaseInfo;
            }


        return null ;
    }
    @RequestMapping("updateProductBaseInfo")
    public boolean updateProduct(@RequestBody ProductBaseInfo productBaseInfo) {



            System.out.println("===========日志===========: 接收到更新商品库存的请求，商品id=" + productBaseInfo.getPid() + ", 商品库存数量=" + productBaseInfo.getInventory());


            Request request = new ProductBaseInfoDBUpdateRequest(productBaseInfo, productBaseInfoService);
            RequestAsyncProcess.process(request);
        return  true ;



    }
    @RequestMapping("getProductForUpdate")
    public Product getProductForUpdate(long pid){

        Product product = this.productService.getProductForUpdate(pid);
        ProductSpec spec = this.productSpecService.getProductSpec(product.getSpec().getSid()) ;
        spec.setProductName(this.productNameService.getProductName(spec.getProductName().getNid()));
        product.setSpec(spec);
        return product ;
    }

}
